package org.geektimes.projects.user.repository;

import org.geektimes.projects.user.domain.User;
import org.geektimes.projects.user.orm.jpa.DelegatingEntityManager;
import org.geektimes.projects.user.sql.DBConnectionManager;

import javax.annotation.Resource;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import javax.persistence.TypedQuery;
import java.util.*;
import java.util.function.Consumer;
import java.util.logging.Level;
import java.util.logging.Logger;


/**
 * @author : zghuang
 * @date : 2021/3/11 20:46
 */
public class JpaDatabseUserRepository implements UserRepository {
    private static Logger logger = Logger.getLogger(DatabaseUserRepository.class.getName());
    @Resource(name="bean/EntityManager")
    private DelegatingEntityManager entityManager;

    public void setEntityManager(DelegatingEntityManager entityManager) {
        this.entityManager = entityManager;
    }

    /**
     * 通用处理方式
     */
    private static Consumer<Throwable> COMMON_EXCEPTION_HANDLER = e -> logger.log(Level.SEVERE, e.getMessage());

    @Resource(name="bean/DBConnectionManager")
    private DBConnectionManager dbConnectionManager;

    public void setDbConnectionManager(DBConnectionManager dbConnectionManager) {
        this.dbConnectionManager = dbConnectionManager;
    }

    public JpaDatabseUserRepository() {
    }

    @Override
    public boolean save(User user) {
//        EntityTransaction transaction = entityManager.getTransaction();
        try {
            user.setPassword(Base64.getEncoder().encodeToString(user.getPassword().getBytes()));
//            transaction.begin();
            entityManager.persist(user);
//            transaction.commit();
            return true;
        } catch (Exception e) {
            logger.log(Level.SEVERE,e.getMessage());
//            transaction.rollback();
            return false;
        }
    }

    @Override
    public boolean deleteById(Long userId) {
        EntityTransaction transaction = entityManager.getTransaction();
        User user = entityManager.find(User.class, userId);
        transaction.begin();
        entityManager.remove(user);
        transaction.commit();
        return true;
    }

    @Override
    public boolean update(User user) {
        return false;
    }

    @Override
    public User getById(Long userId) {
        User user = entityManager.find(User.class, userId);
        return user;
    }

    @Override
    public User getByNameAndPassword(String userName, String password) {
        EntityTransaction transaction = entityManager.getTransaction();
        User user = null;
        try {
            transaction.begin();
            String hql = "SELECT user FROM User user WHERE user.name = :name and user.password = :pass";
            Query query = entityManager.createQuery(hql).setParameter("name", userName).
                    setParameter("pass", password);
            user = (User) query.getSingleResult();
            transaction.commit();
            return user;
        }catch (Exception e){
            transaction.rollback();
            return null;
        }

    }

    @Override
    public Collection<User> getAll() {
        TypedQuery<User> query = entityManager.createQuery("select U.id,U.name,U.password,U.email,U.phoneNumber from User U", User.class);
        return query.getResultList();
    }

    private static String mapColumnLabel(String fieldName) {
        return fieldName;
    }

    /**
     * 数据类型与 ResultSet 方法名映射
     */
    static Map<Class, String> resultSetMethodMappings = new HashMap<>();

    static Map<Class, String> preparedStatementMethodMappings = new HashMap<>();

    static {
        resultSetMethodMappings.put(Long.class, "getLong");
        resultSetMethodMappings.put(String.class, "getString");

        preparedStatementMethodMappings.put(Long.class, "setLong"); // long
        preparedStatementMethodMappings.put(String.class, "setString"); //


    }
}
